home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 2
/
AACD 2.iso
/
AACD
/
Magazine
/
GraphicsCards
/
StormMesa
/
src
/
bitmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-04
|
8KB
|
295 lines
/* $Id: bitmap.c,v 3.10 1998/07/30 02:39:18 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.0
* Copyright (C) 1995-1998 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Log: bitmap.c,v $
* Revision 3.10 1998/07/30 02:39:18 brianp
* feedback/selection modes didn't work
*
* Revision 3.9 1998/07/29 04:07:53 brianp
* feedback was returning wrong values
*
* Revision 3.8 1998/05/04 23:54:35 brianp
* include stdio.h since assert.h needs it on some systems
*
* Revision 3.7 1998/03/27 03:30:36 brianp
* fixed G++ warnings
*
* Revision 3.6 1998/03/25 01:24:11 brianp
* glBitmap in feedback mode returned X,Y offset by bitmap origin (wrong)
*
* Revision 3.5 1998/03/05 03:07:56 brianp
* check for invalid raster pos in gl_direct_bitamp()
*
* Revision 3.4 1998/02/27 00:54:29 brianp
* NULL bitmap image caused assertion- fixed
*
* Revision 3.3 1998/02/15 01:32:59 brianp
* updated driver bitmap function
*
* Revision 3.2 1998/02/08 20:23:49 brianp
* lots of bitmap rendering changes
*
* Revision 3.1 1998/02/04 00:33:45 brianp
* fixed a few cast problems for Amiga StormC compiler
*
* Revision 3.0 1998/01/31 20:47:29 brianp
* initial rev
*
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "bitmap.h"
#include "context.h"
#include "feedback.h"
#include "image.h"
#include "macros.h"
#include "pb.h"
#include "pixel.h"
#include "types.h"
#endif
/*
* Render bitmap data.
*/
static void render_bitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
struct pixel_buffer *PB = ctx->PB;
GLint row, col;
GLint pz;
if (!bitmap)
return;
if (ctx->NewState) {
gl_update_state(ctx);
PB_INIT( PB, GL_BITMAP );
}
if (ctx->Visual->RGBAflag) {
GLint r, g, b, a;
r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
PB_SET_COLOR( ctx, PB, r, g, b, a );
}
else {
PB_SET_INDEX( ctx, PB, ctx->Current.RasterIndex );
}
pz = (GLint) ( ctx->Current.RasterPos[2] * DEPTH_SCALE );
for (row=0; row<height; row++) {
GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( unpack, bitmap,
width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte bitmask = 1;
for (col=0; col<width; col++) {
if (*src & bitmask) {
PB_WRITE_PIXEL( PB, px+col, py+row, pz );
}
bitmask = bitmask << 1;
if (bitmask==0) {
src++;
bitmask = 1;
}
}
PB_CHECK_FLUSH( ctx, PB )
/* get ready for next row */
if (bitmask!=1)
src++;
}
else {
/* Msb first */
GLubyte bitmask = 128;
for (col=0; col<width; col++) {
if (*src & bitmask) {
PB_WRITE_PIXEL( PB, px+col, py+row, pz );
}
bitmask = bitmask >> 1;
if (bitmask==0) {
src++;
bitmask = 128;
}
}
PB_CHECK_FLUSH( ctx, PB )
/* get ready for next row */
if (bitmask!=128)
src++;
}
}
gl_flush_pb(ctx);
}
/*
* Optimized glBitmap
*/
GLboolean gl_direct_bitmap( GLcontext *ctx,
GLsizei width, GLsizei height,
GLfloat xorig, GLfloat yorig,
GLfloat xmove, GLfloat ymove,
const GLubyte *bitmap )
{
GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
GLboolean completed = GL_FALSE;
if (ctx->Current.RasterPosValid==GL_FALSE) {
return GL_TRUE; /* command completed as a no-op */
}
if (ctx->RenderMode != GL_RENDER)
return GL_FALSE;
if (ctx->Driver.Bitmap) {
/* let device driver try to render the bitmap */
completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
&ctx->Unpack, bitmap );
}
if (!completed) {
/* We can handle an pixel unpacking combo! */
render_bitmap( ctx, px, py, width, height, &ctx->Unpack, bitmap );
}
/* update raster position */
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
return GL_TRUE;
}
/* Simple unpacking parameters: */
static struct gl_pixelstore_attrib NoUnpack = {
1, /* Alignment */
0, /* RowLength */
0, /* SkipPixels */
0, /* SkipRows */
0, /* ImageHeight */
0, /* SkipImages */
GL_FALSE, /* SwapBytes */
GL_FALSE /* LsbFirst */
};
/*
* Execute a glBitmap command:
* 1. check for errors
* 2. feedback/render/select
* 3. advance raster position
*/
void gl_Bitmap( GLcontext* ctx,
GLsizei width, GLsizei height,
GLfloat xorig, GLfloat yorig,
GLfloat xmove, GLfloat ymove,
struct gl_image *bitmap )
{
if (width<0 || height<0) {
gl_error( ctx, GL_INVALID_VALUE, "glBitmap" );
return;
}
if (INSIDE_BEGIN_END(ctx)) {
gl_error( ctx, GL_INVALID_OPERATION, "glBitmap" );
return;
}
if (ctx->Current.RasterPosValid==GL_FALSE) {
/* do nothing */
return;
}
assert(bitmap->Type == GL_BITMAP);
assert(bitmap->Format == GL_COLOR_INDEX);
if (ctx->RenderMode==GL_RENDER) {
GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
GLboolean completed = GL_FALSE;
if (ctx->Driver.Bitmap) {
/* let device driver try to render the bitmap */
completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
&NoUnpack,
(const GLubyte *) bitmap->Data );
}
if (!completed) {
/* use generic function */
render_bitmap( ctx, px, py, width, height, &NoUnpack,
(const GLubyte *) bitmap->Data );
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
GLfloat color[4], texcoord[4], invq;
color[0] = ctx->Current.RasterColor[0];
color[1] = ctx->Current.RasterColor[1];
color[2] = ctx->Current.RasterColor[2];
color[3] = ctx->Current.RasterColor[3];
if (ctx->Current.TexCoord[3] == 0.0)
invq = 1.0F;
else
invq = 1.0F / ctx->Current.RasterTexCoord[3];
texcoord[0] = ctx->Current.RasterTexCoord[0] * invq;
texcoord[1] = ctx->Current.RasterTexCoord[1] * invq;
texcoord[2] = ctx->Current.RasterTexCoord[2] * invq;
texcoord[3] = ctx->Current.RasterTexCoord[3];
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
gl_feedback_vertex( ctx,
ctx->Current.RasterPos[0],
ctx->Current.RasterPos[1],
ctx->Current.RasterPos[2],
ctx->Current.RasterPos[3],
color, ctx->Current.RasterIndex, texcoord );
}
else if (ctx->RenderMode==GL_SELECT) {
/* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */
}
/* update raster position */
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
}